package com.sfeir.gwt.webding.client.showcase;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.HasDirection;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.LazyPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TabBar;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.sfeir.gwt.webding.client.component.menu.Item;
import com.sfeir.gwt.webding.client.component.menu.Menu;


public abstract class LazyTab extends LazyPanel implements SelectionHandler<Integer> {

    /**
     * The default style name.
     */
    private static final String DEFAULT_STYLE_NAME = "sc-ContentWidget";

    /**
     * The static loading image displayed when loading CSS or source code.
     */
    private static String loadingImage;

    /**
     * The widget used to display source code.
     */
    private HTML sourceWidget = null;

    /**
     * A boolean indicating whether or not the RPC request for the source code has been sent.
     */
    private boolean sourceLoaded = false;

    /**
     * A vertical panel that holds the demo widget once it is initialized.
     */
    private VerticalPanel widgetVpanel;

    /**
     * The tab bar of options.
     */
    protected TabBar tabBar = null;

    /**
     * The deck panel with the contents.
     */
    private DeckPanel deckPanel = null;
    
    private Widget widgetExemple = null;
    
    /**
     * The decorator around the content.
     */
    private DecoratorPanel contentDecorator;

    /**
     * The main wrapper around the content and content title.
     */
    private Grid contentLayout;

    /**
     * The wrapper around the content.
     */
    private SimplePanel contentWrapper;


    public LazyTab() {
        super();
        tabBar = new TabBar();
    }

    protected Widget createWidget() {
        deckPanel = new DeckPanel();

        contentLayout = new Grid(2, 1);
        contentLayout.setSize("800px", "100%");
        contentLayout.setCellPadding(0);
        contentLayout.setCellSpacing(0);
        contentDecorator = new DecoratorPanel();
        contentDecorator.setWidget(contentLayout);
        contentDecorator.addStyleName(DEFAULT_STYLE_NAME + "-content-decorator");
       
        CellFormatter formatter = contentLayout.getCellFormatter();

        // Add the content title
        contentLayout.setWidget(0, 0, tabBar);
        formatter.setStyleName(0, 0, DEFAULT_STYLE_NAME + "-content-title");

        // Add the content wrapper
        contentWrapper = new SimplePanel();
        contentLayout.setWidget(1, 0, contentWrapper);
        formatter.setStyleName(1, 0, DEFAULT_STYLE_NAME + "-content-wrapper");
        contentWrapper.setWidget(deckPanel);
        setStyleName(DEFAULT_STYLE_NAME);

        // Add a tab handler
        tabBar.addSelectionHandler(this);

        // Create a container for the main example
        widgetVpanel = new VerticalPanel();
        add(widgetVpanel, "Exemple");

        // Add the name
        HTML nameWidget = new HTML(getName());
        nameWidget.setStyleName(DEFAULT_STYLE_NAME + "-name");
        widgetVpanel.add(nameWidget);

        // Add the description
        HTML descWidget = new HTML(getDescription());
        descWidget.setStyleName(DEFAULT_STYLE_NAME + "-description");
        widgetVpanel.add(descWidget);
        
        //Add Widget
        widgetExemple = createTab();
        widgetVpanel.add(widgetExemple);

        // Add source code tab
        sourceWidget = new HTML();
        add(sourceWidget, "Source");

        selectTab(0);
        return contentDecorator;
    }

    public void onSelection(SelectionEvent<Integer> event) {
        // Show the associated widget in the deck panel
        int tabIndex = event.getSelectedItem().intValue();
        deckPanel.showWidget(tabIndex);

        // Load the source code
        if (!sourceLoaded && tabIndex == 1) {
            sourceLoaded = true;
            String className = this.getClass().getName();
            className = className.substring(className.lastIndexOf(".") + 1);
            requestSourceContents(ShowcaseConstants.DST_SOURCE_EXAMPLE + className + ".html", sourceWidget, null);
        }
    }

    /**
     * Select a tab.
     * @param index
     *            the tab index
     */
    public void selectTab(int index) {
        tabBar.selectTab(index);
    }

    /**
     * Add an item to this content widget. Should not be called before {@link #onInitializeComplete}
     * has been called.
     * @param w
     *            the widget to add
     * @param tabText
     *            the text to display in the tab
     */
    public void add(Widget w, String tabText) {
        tabBar.addTab(tabText);
        deckPanel.add(w);
    }

    /**
     * Load the contents of a remote file into the specified widget.
     * 
     * @param url a partial path relative to the module base URL
     * @param target the target Widget to place the contents
     * @param callback the callback when the call completes
     */
    protected void requestSourceContents(String url, final HTML target,
        final RequestCallback callback) {
      // Show the loading image
      if (loadingImage == null) {
        loadingImage = "<img src=\"" + GWT.getModuleBaseURL()
            + "ajax-loader.gif\">";
      }
      target.setDirection(HasDirection.Direction.LTR);
      DOM.setStyleAttribute(target.getElement(), "textAlign", "left");
      target.setHTML("&nbsp;&nbsp;" + loadingImage);

      // Request the contents of the file
      RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
          GWT.getModuleBaseURL() + url);
      RequestCallback realCallback = new RequestCallback() {
        public void onError(Request request, Throwable exception) {
          target.setHTML("Cannot find resource");
          if (callback != null) {
            callback.onError(request, exception);
          }
        }

        public void onResponseReceived(Request request, Response response) {
          target.setHTML(response.getText());
          if (callback != null) {
            callback.onResponseReceived(request, response);
          }
        }
      };
      builder.setCallback(realCallback);

      // Send the request
      try {
        builder.send();
      } catch (RequestException e) {
        realCallback.onError(null, e);
      }
    }
    
    /**
     * Get the description of this example.
     * @return a description for this example
     */
    public abstract String getDescription();

    /**
     * Get the name of this example to use as a title.
     * @return a name for this example
     */
    public abstract String getName();

    /**
     * Cree le composant
     * @return
     */
    protected abstract Widget createTab();

    public static void buildSampleMenu(Menu menu) {
        Item beethoven = new Item("Beethoven");
        Item brahms = new Item("Brahms");
        Item mozart = new Item("Mozart");

        Item beethovenConcertos = new Item("Concertos");
        beethovenConcertos.add(new Item("n ° 1 - C"));
        beethovenConcertos.add(new Item("n ° 2 - B-Flat Major"));
        beethovenConcertos.add(new Item("n ° 3 - C Minor"));
        beethovenConcertos.add(new Item("n ° 4 - G Major"));
        beethovenConcertos.add(new Item("n ° 5 - mi bémol majeur"));
        Item beethovenQuatuors = new Item("Quatuors");
        beethovenQuatuors.add(new Item("Six Quatuors à cordes"));
        beethovenQuatuors.add(new Item("Trois Quatuors à cordes"));
        beethovenQuatuors.add(new Item("Grosse Fugue pour Quatuors à cordes"));
        Item beethovenSonates = new Item("Sonates");
        beethovenSonates.add(new Item("Sonate en la mineur"));
        beethovenSonates.add(new Item("Sonate en fa majeur"));
        Item beethovenSymphonies = new Item("Symphonies");
        beethovenSymphonies.add(new Item("n ° 1 - D Major"));
        beethovenSymphonies.add(new Item("n ° 2 - D Major"));
        beethovenSymphonies.add(new Item("n ° 3 - E-Flat Major"));
        beethovenSymphonies.add(new Item("n ° 4 - B-Flat Major"));
        beethovenSymphonies.add(new Item("n ° 5 - C Minor"));
        beethovenSymphonies.add(new Item("n ° 6 - F Major"));
        beethovenSymphonies.add(new Item("n ° 7 - Un grand"));
        beethovenSymphonies.add(new Item("n ° 8 - F Major"));
        beethovenSymphonies.add(new Item("n ° 9 - ré mineur"));
        beethoven.add(beethovenConcertos);
        beethoven.add(beethovenQuatuors);
        beethoven.add(beethovenSonates);
        beethoven.add(beethovenSymphonies);

        Item brahmsConcertos = new Item("Concertos");
        brahmsConcertos.add(new Item("Concerto pour violon"));
        brahmsConcertos.add(new Item("Double Concerto - A minor"));
        brahmsConcertos.add(new Item("Concerto pour piano n ° 1 - D minor"));
        brahmsConcertos.add(new Item("Concerto pour piano n ° 2 - si bémol majeur"));
        Item brahmsQuatuors = new Item("Quatuors");
        brahmsQuatuors.add(new Item("Quatuor pour piano n ° 1 - G Minor"));
        brahmsQuatuors.add(new Item("Quatuor pour piano n ° 2 - Un grand"));
        brahmsQuatuors.add(new Item("Quatuor pour piano n ° 3 - C Minor"));
        brahmsQuatuors.add(new Item("Quatuor à cordes n ° 3 - B-flat minor"));
        Item brahmsSonates = new Item("Sonates");
        brahmsSonates.add(new Item("Deux Sonates pour clarinette - F Minor"));
        brahmsSonates.add(new Item("deux sonates pour clarinette - mi bémol majeur"));
        Item brahmsSymphonies = new Item("Symphonies");
        brahmsSymphonies.add(new Item("n ° 1 - C Minor"));
        brahmsSymphonies.add(new Item("n ° 2 - ré mineur"));
        brahmsSymphonies.add(new Item("n ° 3 - E-Flat Major"));
        brahmsSymphonies.add(new Item("n ° 4 - E Minor"));
        brahms.add(brahmsConcertos);
        brahms.add(brahmsQuatuors);
        brahms.add(brahmsSonates);
        brahms.add(brahmsSymphonies);

        Item mozartConcertos = new Item("Concertos");
        mozartConcertos.add(new Item("Concerto pour piano n ° 12"));
        mozartConcertos.add(new Item("Concerto pour piano n ° 17"));
        mozartConcertos.add(new Item("Concerto pour clarinette"));
        mozartConcertos.add(new Item("Concerto pour violon n ° 5"));
        mozartConcertos.add(new Item("Concerto pour violon n ° 4"));
        mozart.add(mozartConcertos);

        menu.add(beethoven);
        menu.add(brahms);
        menu.add(mozart);
    }

    public static List<String> listWords = Arrays.asList("1337", "apple", "about", "ant", "bruce", "banana", "bobv", "canada", "coconut", "compiler", "donut", "deferred binding", "dessert topping", "eclair", "ecc", "frog attack", "floor wax",
                                                         "fitz", "google", "gosh", "gwt", "hollis", "haskell", "hammer", "in the flinks", "internets", "ipso facto", "jat", "jgw", "java", "jens", "knorton", "kaitlyn", "kangaroo", "la grange", "lars",
                                                         "love", "morrildl", "max", "maddie", "mloofle", "mmendez", "nail", "narnia", "null", "optimizations", "obfuscation", "original", "ping pong", "polymorphic", "pleather", "quotidian", "quality",
                                                         "qu'est-ce que c'est", "ready state", "ruby", "rdayal", "subversion", "superclass", "scottb", "tobyr", "the dans", "~ tilde", "undefined", "unit tests", "under 100ms", "vtbl", "vidalia",
                                                         "vector graphics", "w3c", "web experience", "work around", "w00t!", "xml", "xargs", "xeno", "yacc", "yank (the vi command)", "zealot", "zoe", "zebra");
    public static Map<String, String> listDepartement = new LinkedHashMap<String, String>();
    static {
        listDepartement.put("01", "Ain");
        listDepartement.put("01", "Ain");
        listDepartement.put("02", "Aisne");
        listDepartement.put("03", "Allier");
        listDepartement.put("04", "Alpes-de-Haute-Provence");
        listDepartement.put("05", "Hautes-Alpes");
        listDepartement.put("06", "Alpes-Maritimes");
        listDepartement.put("07", "Ardèche");
        listDepartement.put("08", "Ardennes");
        listDepartement.put("09", "Ariège");
        listDepartement.put("10", "Aube");
        listDepartement.put("11", "Aude");
        listDepartement.put("12", "Aveyron");
        listDepartement.put("13", "Bouches-du-Rhône");
        listDepartement.put("14", "Calvados");
        listDepartement.put("15", "Cantal");
        listDepartement.put("16", "Charente");
        listDepartement.put("17", "Charente-Maritime");
        listDepartement.put("18", "Cher");
        listDepartement.put("19", "Corrèze");
        listDepartement.put("2A", "Corse-du-Sud");
        listDepartement.put("2B", "Haute-Corse");
        listDepartement.put("21", "Côte-d'Or");
        listDepartement.put("22", "Côtes-d'Armor");
        listDepartement.put("23", "Creuse");
        listDepartement.put("24", "Dordogne");
        listDepartement.put("25", "Doubs");
        listDepartement.put("26", "Drôme");
        listDepartement.put("27", "Eure");
        listDepartement.put("28", "Eure-et-Loir");
        listDepartement.put("29", "Finistère");
        listDepartement.put("30", "Gard");
        listDepartement.put("31", "Haute-Garonne");
        listDepartement.put("32", "Gers");
        listDepartement.put("33", "Gironde");
        listDepartement.put("34", "Hérault");
        listDepartement.put("35", "Ille-et-Vilaine");
        listDepartement.put("36", "Indre");
        listDepartement.put("37", "Indre-et-Loire");
        listDepartement.put("38", "Isère");
        listDepartement.put("39", "Jura");
        listDepartement.put("40", "Landes");
        listDepartement.put("41", "Loir-et-Cher");
        listDepartement.put("42", "Loire");
        listDepartement.put("43", "Haute-Loire");
        listDepartement.put("44", "Loire-Atlantique");
        listDepartement.put("45", "Loiret");
        listDepartement.put("46", "Lot");
        listDepartement.put("47", "Lot-et-Garonne");
        listDepartement.put("48", "Lozère");
        listDepartement.put("49", "Maine-et-Loire");
        listDepartement.put("50", "Manche");
        listDepartement.put("51", "Marne");
        listDepartement.put("52", "Haute-Marne");
        listDepartement.put("53", "Mayenne");
        listDepartement.put("54", "Meurthe-et-Moselle");
        listDepartement.put("55", "Meuse");
        listDepartement.put("56", "Morbihan");
        listDepartement.put("57", "Moselle");
        listDepartement.put("58", "Nièvre");
        listDepartement.put("59", "Nord");
        listDepartement.put("60", "Oise");
        listDepartement.put("61", "Orne");
        listDepartement.put("62", "Pas-de-Calais");
        listDepartement.put("63", "Puy-de-Dôme");
        listDepartement.put("64", "Pyrénées-Atlantiques");
        listDepartement.put("65", "Hautes-Pyrénées");
        listDepartement.put("66", "Pyrénées-Orientales");
        listDepartement.put("67", "Bas-Rhin");
        listDepartement.put("68", "Haut-Rhin");
        listDepartement.put("69", "Rhône");
        listDepartement.put("70", "Haute-Saône");
        listDepartement.put("71", "Saône-et-Loire");
        listDepartement.put("72", "Sarthe");
        listDepartement.put("73", "Savoie");
        listDepartement.put("74", "Haute-Savoie");
        listDepartement.put("75", "Paris");
        listDepartement.put("76", "Seine-Maritime");
        listDepartement.put("77", "Seine-et-Marne");
        listDepartement.put("78", "Yvelines");
        listDepartement.put("79", "Deux-Sèvres");
        listDepartement.put("80", "Somme");
        listDepartement.put("81", "Tarn");
        listDepartement.put("82", "Tarn-et-Garonne");
        listDepartement.put("83", "Var");
        listDepartement.put("84", "Vaucluse");
        listDepartement.put("85", "Vendée");
        listDepartement.put("86", "Vienne");
        listDepartement.put("87", "Haute-Vienne");
        listDepartement.put("88", "Vosges");
        listDepartement.put("89", "Yonne");
        listDepartement.put("90", "Territoire de Belfort");
        listDepartement.put("91", "Essonne");
        listDepartement.put("92", "Hauts-de-Seine");
        listDepartement.put("93", "Seine-Saint-Denis");
        listDepartement.put("94", "Val-de-Marne");
        listDepartement.put("95", "Val-d'Oise");

    }

}
